package com.example.myapplication;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okhttp3.Response;

import java.util.Objects;
import java.util.UUID;

/**
 * WebSocketManager 封装了 OkHttp 的 WebSocket 功能
 * 提供：
 * 1. 建立 WebSocket 连接
 * 2. 发送消息
 * 3. 接收消息和错误回调
 * 4. 断开连接
 * <p>
 * 使用示例：
 * WebSocketManager wsManager = new WebSocketManager(new WebSocketManager.OnWebSocketListener() {
 *     &#064;Override
 *     public void onError(String errorMessage) { ... }
 *     &#064;Override
 *     public void onMessageReceived(String message) { ... }
 * });
 * wsManager.connect("wss://example.com/ws");
 * wsManager.sendMessage("{\"type\":\"ping\"}");
 * wsManager.disconnect();
 */
public class WebSocketManager {

    private static final String TAG = "WebSocketManager";

    /** WebSocket 对象，用于发送和接收消息 */
    private WebSocket webSocket;

    /** WebSocket 是否已连接 */
    private boolean connected = false;

    /** OkHttp 客户端，负责创建 WebSocket */
    private final OkHttpClient client;

    /** WebSocket 消息回调接口 */
    private final OnWebSocketListener listener;

    /** 每个连接唯一标识，用于调试或区分不同连接 */
    private final String connectionId;

    /**
     * 构造函数
     * @param listener 消息回调接口
     */
    public WebSocketManager(OnWebSocketListener listener) {
        this.listener = listener;
        client = new OkHttpClient();
        connectionId = UUID.randomUUID().toString(); // 生成唯一连接ID
    }

    /**
     * 检查 WebSocket 是否已连接
     * @return true 表示连接正常
     */
    public boolean isConnected() {
        return connected && webSocket != null;
    }

    /**
     * 建立 WebSocket 连接
     * @param url WebSocket 服务器地址，例如 "wss://example.com/ws"
     */
    public void connect(String url) {
        try {
            Request request = new Request.Builder().url(url).build();

            webSocket = client.newWebSocket(request, new WebSocketListener() {

                /** WebSocket 成功连接时回调 */
                @Override
                public void onOpen(@NonNull WebSocket webSocket, @NonNull Response response) {
                    Log.d(TAG, "WebSocket connected with ID: " + connectionId);
                    connected = true;
                }

                /** 收到服务器消息时回调 */
                @Override
                public void onMessage(@NonNull WebSocket webSocket, @NonNull String text) {
                    Log.d(TAG, "Message received: " + text);
                    if (listener != null) {
                        // 切换到主线程回调，保证 UI 可以安全操作
                        new Handler(Looper.getMainLooper()).post(() -> listener.onMessageReceived(text));
                    }
                }

                /** 连接失败或出错时回调 */
                @Override
                public void onFailure(@NonNull WebSocket webSocket, @NonNull Throwable t, Response response) {
                    Log.e(TAG, "WebSocket error: " + t.getMessage());
                    connected = false;
                    if (listener != null) {
                        new Handler(Looper.getMainLooper()).post(() -> listener.onError(Objects.requireNonNull(t.getMessage())));
                    }
                }

                /** WebSocket 被关闭时回调 */
                @Override
                public void onClosed(@NonNull WebSocket webSocket, int code, @NonNull String reason) {
                    Log.d(TAG, "WebSocket closed: " + reason);
                    connected = false;
                }
            });
        } catch (Exception e) {
            connected = false;
            if (listener != null) {
                new Handler(Looper.getMainLooper()).post(() -> listener.onError(Objects.requireNonNull(e.getMessage())));
            }
        }
    }

    /**
     * 断开 WebSocket 连接
     * 如果已连接，会发送 1000 (Normal Closure) 信号给服务器
     */
    public void disconnect() {
        if (webSocket != null) {
            webSocket.close(1000, "Client disconnected");
            webSocket = null;
        }
        connected = false;
    }

    /**
     * 发送消息到服务器
     * @param message JSON 或字符串消息
     */
    public void sendMessage(@NonNull String message) {
        if (webSocket != null && connected) {
            webSocket.send(message);
        }
    }

    /**
     * WebSocket 消息回调接口
     * 实现该接口以接收消息或错误信息
     */
    public interface OnWebSocketListener {
        /** 发生错误回调 */
        void onError(@NonNull String errorMessage);

        /** 收到消息回调 */
        void onMessageReceived(@NonNull String message);
    }
}
